package ee.nlp.evn.entities;

import java.util.ArrayList;

public class Word {
	private String usedForm;
	private ArrayList<ArrayList<Annotation>> tags;
	private int currentVariant;

	public Word(String s) {
		this.usedForm = s;
		this.currentVariant = 0;
		tags = new ArrayList<ArrayList<Annotation>>();
	}

	/**
	 * @return the usedForm
	 */
	public String getUsedForm() {
		return usedForm;
	}

	/**
	 * @param usedForm
	 *            the usedForm to set
	 */
	public void setUsedForm(String usedForm) {
		this.usedForm = usedForm;
	}

	/**
	 * @return the tags
	 */
	public ArrayList<ArrayList<Annotation>> getAllTags() {
		return tags;
	}

	public ArrayList<Annotation> getTags() {
		return getTags(currentVariant);
	}

	public ArrayList<Annotation> getTags(int variant) {
		return tags.get(variant);
	}

	/**
	 * @param tags
	 *            the tags to set
	 */
	public void setTags(ArrayList<Annotation> tags) {
		setTags(tags, currentVariant);
	}

	public void setTags(ArrayList<Annotation> tags, int variant) {
		if (this.tags.size() >= variant) {
			this.tags.set(variant, tags);
			this.currentVariant = variant;
		} else {
			this.tags.add(tags);
			this.currentVariant = this.tags.size() - 1;
		}
	}

	public String getTagForm() {
		String result = getUsedForm() + " :- ";
		for (int v = 0; v < tags.size(); v++) {
			result += "{(" + String.valueOf(v) + ") ";
			if (tags.get(v) != null) {
				for (Annotation a : tags.get(v)) {
					if (a != null)
						result += a.getLevel() + ":" + a.getTag() + "; ";
				}
			}
			result += "}";
		}
		return result;
	}

	public boolean includeTag(String tag, String value) {
		boolean result = false;
		for (int v = 0; v < tags.size(); v++) {
			if (tags.get(v) != null) {
				for (Annotation a : tags.get(v)) {
					if (a.getLevel().equalsIgnoreCase(tag)) {
						if ("trunk".equals(a.getLevel())) {
							if (a.getTag().startsWith(value + "+")) {
								result = true;
								currentVariant = v;
								return result;
							}
						} else {
							if (a.getTag().equals(value)) {
								result = true;
								currentVariant = v;
								return result;
							}
						}
					}
				}
			}
		}
		return result;
	}

	public boolean includeTag(String tag, String value, int startingFromVariant) {
		boolean result = false;
		for (int v = startingFromVariant; v < tags.size(); v++) {
			if (tags.get(v) != null) {
				for (Annotation a : tags.get(v)) {
					if (a.getLevel().equalsIgnoreCase(tag)) {
						if ("trunk".equals(a.getLevel())) {
							if (a.getTag().startsWith(value + "+")) {
								result = true;
								currentVariant = v;
								return result;
							}
						} else {
							if (a.getTag().equals(value)) {
								result = true;
								currentVariant = v;
								return result;
							}
						}
					}
				}
			}
		}
		return result;
	}

	public boolean isOLP(String type) {
		return getUsedForm().isEmpty() && includeTag("OLP", type);
	}

	public String getTrunk() {
		return getTrunk(currentVariant);
	}

	public String getTrunk(int variant) {
		String result = "";
		if (tags.get(variant) != null) {
			for (Annotation a : tags.get(variant)) {
				if (a.getLevel().equals("trunk")) {
					result = a.getTag();
					break;
				}
			}
		}
		return result;
	}

	public String[] getTrunks() {
		String[] result = new String[tags.size()];
		for (int v = 0; v < tags.size(); v++) {
			if (tags.get(v) != null) {
				for (Annotation a : tags.get(v)) {
					if (a.getLevel().equals("trunk")) {
						result[v] = a.getTag();
						break;
					}
				}
			}
		}
		return result;
	}

	public void addTag(String tag, String value, int variant) {
		while (tags.size() - 1 < variant) {
			tags.add(new ArrayList<Annotation>());
		}
		Annotation a = new Annotation(tag, value);
		tags.get(variant).add(a);
	}

	public void addTag(String tag, String value) {
		addTag(tag, value, currentVariant);
	}

	public void addNewVariant() {
		currentVariant = tags.size();
		if (tags.get(currentVariant) == null) {
			tags.add(new ArrayList<Annotation>());
		}
	}

	public int getCurrentVariant() {
		return this.currentVariant;
	}

	public boolean setCurrentVariant(int variant) {
		if (variant < tags.size()) {
			this.currentVariant = variant;
			return true;
		} else {
			return false;
		}
	}

}
